//
//  XFSocket.m
//  TestSocket
//
//  Created by ukongm on 17/1/13.
//  Copyright © 2017年 ukongm. All rights reserved.
//

#import "XFSocket.h"

@interface XFSocket()<NSStreamDelegate>

@end

@implementation XFSocket
{
    NSInputStream* _inputStream;
    NSOutputStream* _outputStream;
    id<XFSocketDelegate> _delegate; // 代理指针
    
//    BOOL _inputSuccess; //输入流准备好了
//    BOOL _outputSuccess; //输出流准备好了
    
    NSString* _adress; // 保存下来的地址
    int _port; //保存下来的端口
}

- (void)connectForAdress:(NSString *)adress andPort:(int)port andDelegate:(id<XFSocketDelegate>)delegate{
    
    _delegate = delegate;
    _adress = adress;
    _port = port;
    
    CFReadStreamRef readStream; //输入流
    CFWriteStreamRef writeStream; //输出流
    
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)adress, port, &readStream, &writeStream);
    
    _inputStream = (__bridge NSInputStream*)readStream;
    _outputStream = (__bridge NSOutputStream*)writeStream;
    
//    _inputStream.delegate = self;
//    _outputStream.delegate = self;
    
    [self open];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    /*
     NSStreamEventNone = 0,
     NSStreamEventOpenCompleted = 1UL << 0,
     NSStreamEventHasBytesAvailable = 1UL << 1,
     NSStreamEventHasSpaceAvailable = 1UL << 2,
     NSStreamEventErrorOccurred = 1UL << 3,
     NSStreamEventEndEncountered = 1UL << 4

     */
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            //打开完毕
            _status = XFSocketConnectStatusConnect;
            
            if (_inputStream == aStream) {
                    
                if (_delegate != nil && [_delegate respondsToSelector:@selector(socket:connectSuccessForStatus:)]) {
                    
                    [_delegate socket:self connectSuccessForStatus:_status];
                }
            }
            break;
        case NSStreamEventHasBytesAvailable:
        {
            //有数据回来
            NSData* data = [self readData];
            
            if (_delegate != nil && [_delegate respondsToSelector:@selector(socket:accpetForData:)]) {
                
                [_delegate socket:self accpetForData:data];
            }
            
            break;
        }
        case NSStreamEventHasSpaceAvailable:
            
            break;
        case NSStreamEventErrorOccurred:
            //打开失败
            if (_inputStream == aStream) {
                _status = XFSocketConnectStatusNoConnect;
                
                [self closeForStream:aStream];
                
                if (_delegate != nil && [_delegate respondsToSelector:@selector(socket:connectFailForStatus:)]) {
                    [_delegate socket:self connectFailForStatus:_status];
                }
            }
            break;
        case NSStreamEventEndEncountered:
            //连接中断
            _status = XFSocketConnectStatusNoConnect;
            [self closeForStream:aStream];
            
            if (_delegate != nil && [_delegate respondsToSelector:@selector(socket:connectEndForStatus:)]) {
                [_delegate socket:self connectEndForStatus:_status];
            }
            
            break;
            
        default:
            break;
    }
}

- (NSData*)readData{
    //有数据过来
    uint8_t byte[1024];
    
    NSInteger len = [_inputStream read:byte maxLength:sizeof(byte)];
    
    NSData* data = [NSData dataWithBytes:byte length:len];
    
    return data;
}

- (void)sendData:(NSData *)data{
    
    dispatch_queue_t queue = dispatch_queue_create("xf", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        if (_status == XFSocketConnectStatusConnect) {
            [_outputStream write:data.bytes maxLength:data.length];
        }else{
            
            if (_delegate != nil && [_delegate respondsToSelector:@selector(socket:sendFailForData:)]) {
                [_delegate socket:self sendFailForData:data];
            }
        }
    });
}

- (void)closeForStream:(NSStream*)stream{
    [stream close];
    [stream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    stream = nil;
}

- (void)openForStream:(NSStream*)stream{
    
    stream.delegate = self;
    [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [stream open];
}

- (void)close{
    
    _status = XFSocketConnectStatusNoConnect;
    
    if (_inputStream) {
        [self closeForStream:_inputStream];
//        _inputStream = nil;
    }
    
    if (_outputStream) {
        [self closeForStream:_outputStream];
//        _outputStream = nil;
    }
}

- (void)reset{
    
    [self close];
    
    [self connectForAdress:_adress andPort:_port andDelegate:_delegate];
//    [self open];
}

- (void)open{
    
    //添加到主循环上
    if (_inputStream) {
        [self openForStream:_inputStream];
    }
    if (_outputStream) {
        [self openForStream:_outputStream];
    }
}

@end
